{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "93548b64",
   "metadata": {},
   "source": [
    "# [Py4Hw User Guide](../UserGuide.ipynb)> 1.4 Logic\n",
    "###  [Next: 1.5 Ports](Ports.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0ac5cbe",
   "metadata": {},
   "source": [
    "All Logic blocks inherit from the class Logic.\n",
    "When you create a Hardware block you must create a class inheriting from Logic.\n",
    "Each object must have a parent and a name. This is implemented in the base class, so the constructor of your block must call the base class's constructor with parent and name.\n",
    "\n",
    "<pre>\n",
    "    super().__init__(parent, name)\n",
    "</pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67e16456",
   "metadata": {},
   "source": [
    "Logic class has the following member variables (AKA fields)\n",
    " \n",
    "|Field |Description |\n",
    "| :-- | :-- |\n",
    "| parent | The parent circuit of this circuit. It must be also an object derived from the Logic class, except fot the HWSystem object, which parent is None |\n",
    "| name | An string with the name of the object. This name must be unique among the parent's children |\n",
    "| inPorts | A list with the input ports of the circuit |\n",
    "| outPorts | A list with the output ports of the circuit |\n",
    "| sources | A list with the interface sources of the circuit |\n",
    "| sinks | A list with the interface sinks of the circuit |\n",
    "| children | A dictionary (indexed by name) of the child instances of the circuit |\n",
    "| clockDriver | The clock driver of the circuit. By default is None, meaning that the ClockDriver is inherited from the parent |\n",
    "| _wires | A dictionary (indexed by name) of the internal wires of the circuit |\n",
    "\n",
    "\n",
    "And it has the following member functions (methods).\n",
    "\n",
    "|Method |Description |\n",
    "| :-- | :-- |\n",
    "| __init__ | Constructor of the class |\n",
    "| addIn | Adds an input port |\n",
    "| addOut | Adds an output port |\n",
    "| getInPortByName | Retrieves an input port by its name. This is needed because ports are stored in a list |\n",
    "| getOutPortByName | Retrieves an output port by its name. This is needed because ports are stored in a list |\n",
    "| reconnectIn | Connects an input port with a wire |\n",
    "| addInterfaceSource | Adds the  ports of the source interface to the circuit |\n",
    "| addInterfaceSink | Adds the  ports of the sink interface to the circuit |\n",
    "| appendWire | add wire to internal wires |\n",
    "| wire | create a wire |\n",
    "| wires | create multiple wires |\n",
    "| allLeaves | Obtains all leaf descendants of this circuit |\n",
    "| isPropagatable | Indicates if the circuit implements the propagate function |\n",
    "| isClockable | Indicates if the circuit implements the clock function |\n",
    "| isPrimitive | Indicates if it is either clockable or propagatable |\n",
    "| isStructural | Indicates if it has descendants |\n",
    "| getFullPath | Gets the full of a hierarchy element |\n",
    "| getFromFullPath | Gets a Logic from the full path |\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "495bed7b",
   "metadata": {},
   "source": [
    "Here you can see an example of creating a class to implement an integrator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "1c8717d5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import py4hw\n",
    "\n",
    "class Integrator(py4hw.Logic):\n",
    "    def __init__(self, parent:py4hw.Logic, name:str, a:py4hw.Wire, r:py4hw.Wire):\n",
    "        super().__init__(parent, name)\n",
    "        \n",
    "        self.addIn('a', a)\n",
    "        self.addOut('r', r)\n",
    "        \n",
    "        sum = self.wire('sum', a.getWidth())\n",
    "        py4hw.Add(self, 'sum', a, r, sum)\n",
    "        py4hw.Reg(self, 'r', sum, r)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "60f3c1f2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 335x188 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "hw = py4hw.HWSystem()\n",
    "\n",
    "a = hw.wire('a', 8)\n",
    "r = hw.wire('r', 8)\n",
    "\n",
    "py4hw.Sequence(hw, 'a', [1,2,3,4,5], a)\n",
    "Integrator(hw, 'integrator', a, r)\n",
    "\n",
    "sch = py4hw.Schematic(hw.children['integrator'])\n",
    "\n",
    "sch.draw()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c9c81eec",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
